unit EZStream;

interface

uses
  DebugTools,
  RyuMPEG,
  Windows, SysUtils, Classes, Graphics, SyncObjs;

type
  IEZStream = interface
    ['{F63E69E4-A211-4EB1-8E87-72FFC7F6E7DC}']

    function GetIsOpened: boolean;
    function GetPosition: integer;
    function GetLegnth: int64;

    property IsOpened : boolean read GetIsOpened;
    property Position : integer read GetPosition;
    property Legnth : int64 read GetLegnth;
  end;

  IEZStreamAudio = interface
    ['{F140E24B-0A3F-45EE-AEDC-D854034B1DB4}']

    function GetChannels:integer;
    function GetSampleRate:integer;

    function DecodeAudio(ADataIn:pointer; ASizeIn:integer; var ADataOut:pointer; var ASizeOut:integer):boolean;
  end;

  IEZStreamVideo = interface
    ['{7D5CD263-559A-417B-8F49-CBE3936E0C31}']

    function GetWidth:integer;
    function GetHeight:integer;

    function DecodeVideo(AData:pointer; ASize:integer; ABitmap:TBitmap):boolean;
  end;

  TEZStream = class (TComponent, IEZStream, IEZStreamAudio, IEZStreamVideo)
  private
    FCS : TCriticalSection;
    FRyuMPEG : TRyuMPEGStream;
  private
    FIsOpened: boolean;
    function GetChannels:integer;
    function GetSampleRate:integer;
    function GetWidth:integer;
    function GetHeight:integer;
    function GetIsOpened: boolean;
    function GetPosition: integer;
    function GetLegnth: int64;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure Open(AFileName:string);
    procedure Close;

    function Read(var APacketType:integer; var AData:pointer; var ASize:integer):boolean;

    function DecodeAudio(ADataIn:pointer; ASizeIn:integer; var ADataOut:pointer; var ASizeOut:integer):boolean;
    function DecodeVideo(AData:pointer; ASize:integer; ABitmap:TBitmap):boolean;
  published
    property IsOpened : boolean read GetIsOpened;
    property Position : integer read GetPosition;
    property Legnth : int64 read GetLegnth;
  end;

implementation

{ TEZStream }

procedure TEZStream.Close;
begin
  FCS.Acquire;
  try
    FRyuMPEG.Close;
    FIsOpened := false;
  finally
    FCS.Release;
  end;
end;

constructor TEZStream.Create(AOwner: TComponent);
begin
  inherited;

  FIsOpened := false;

  FCS := TCriticalSection.Create;
  FRyuMPEG := TRyuMPEGStream.Create;
end;

function TEZStream.DecodeAudio(ADataIn: pointer; ASizeIn: integer;
  var ADataOut: pointer; var ASizeOut: integer): boolean;
begin
  FCS.Acquire;
  try
    Result := FRyuMPEG.DecodeAudio(ADataIn, ASizeIn, ADataOut, ASizeOut);
  finally
    FCS.Release;
  end;
end;

function TEZStream.DecodeVideo(AData: pointer; ASize: integer;
  ABitmap: TBitmap): boolean;
begin
  FCS.Acquire;
  try
    Result := FRyuMPEG.DecodeVideo(AData, ASize, ABitmap);
  finally
    FCS.Release;
  end;
end;

destructor TEZStream.Destroy;
begin
  Close;

  FreeAndNil(FRyuMPEG);
  FreeAndNil(FCS);

  inherited;
end;

function TEZStream.GetChannels: integer;
begin
  Result := FRyuMPEG.MediaInfo.AudioInfo.Channels;
end;

function TEZStream.GetHeight: integer;
begin
  Result := FRyuMPEG.MediaInfo.VideoInfo.Height;
end;

function TEZStream.GetIsOpened: boolean;
begin
  Result := FIsOpened;
end;

function TEZStream.GetLegnth: int64;
begin
  Result := FRyuMPEG.MediaInfo.Duration;
end;

function TEZStream.GetPosition: integer;
begin
  Result := FRyuMPEG.Postion;
end;

function TEZStream.GetSampleRate: integer;
begin
  Result := FRyuMPEG.MediaInfo.AudioInfo.SampleRate;
end;

function TEZStream.GetWidth: integer;
begin
  Result := FRyuMPEG.MediaInfo.VideoInfo.Width;
end;

procedure TEZStream.Open(AFileName: string);
begin
  FCS.Acquire;
  try
    FIsOpened := FRyuMPEG.Open(AFileName);
  finally
    FCS.Release;
  end;

  if not FIsOpened then
    raise Exception.Create('TEZStream.Open - Can not open file');
end;

function TEZStream.Read(var APacketType: integer; var AData: pointer;
  var ASize: integer): boolean;
begin
  FCS.Acquire;
  try
    Result := FRyuMPEG.Read(APacketType, AData, ASize);
  finally
    FCS.Release;
  end;
end;

end.
